import java.util.Random;

public class FireflySet {
	private Firefly[] set;
	private OptimizedFunction function;
	private double absorptionCoefficient;
	private double randomnessCoefficient;
	private double baseAttractiveness;
	private Firefly best;
	
	public FireflySet(OptimizedFunction f, int fireflies, double absorption, double randomness, double attractiveness) {
		function = f;
		absorptionCoefficient = absorption;
		randomnessCoefficient = randomness;
		baseAttractiveness = attractiveness;
		set = new Firefly[fireflies];
		for (int i = 0; i < fireflies; i++)
			set[i] = new Firefly(f.getDimension(), this, i + 1);
	}
	
	public OptimizedFunction getFunction() {
		return function;
	}
	
	public double getAbsorption() {
		return absorptionCoefficient;
	}
	
	public double getRandomness() {
		return randomnessCoefficient;
	}
	
	public double getAttractiveness() {
		return baseAttractiveness;
	}
	
	public double[][] getPositions() {
		double[][] positions = new double[set.length][];
		for (int i = 0; i < set.length; i++)
			positions[i] = set[i].getPosition();
		return positions;
	}
	
	public int getBest() {
		return best.getId();
	}
	
	public double[] getBestPosition() {
		return best.getPosition();
	}
	
	public void initPositions() {
		Random r = new Random();
		double[] initialPosition;
		OptimizedFunction.Bound[] bounds = function.getBounds();
		for (Firefly f : set) {
			initialPosition = new double[function.getDimension()];
			for (int i = 0; i < function.getDimension(); i++)
				initialPosition[i] = r.nextDouble() * (bounds[i].highest - bounds[i].lowest) + bounds[i].lowest;
			f.setPosition(initialPosition);
		}
	}
	
	public void iteration() {
		for (int i = 0; i < set.length; i++)
			for (int j = 0; j < set.length; j++)
				if (set[j].getIntensity() > set[i].getIntensity())
					set[i].updatePosition(set[j]);
		best = set[0];
		for (Firefly f : set)
			if (f.getIntensity() > best.getIntensity())
				best = f;
	}
}
